"""
LLM 配置模块 采用 OpenAI 调用方式
通过代理服务实现统一接口
"""
import os
from crewai import LLM
from dotenv import load_dotenv
from typing import Optional, Dict, Any

# 加载环境变量
load_dotenv()

# 默认配置常量
DEFAULT_MODEL = "gpt-4.1"
DEFAULT_API_BASE = "https://api.gpt.ge/v1"
DEFAULT_API_KEY = ""


class CustomLLM(LLM):
    """
    自定义LLM类，禁用stop words支持
    因为某些API服务（如api.gpt.ge）不支持completions中的stop words
    """
    def supports_stop_words(self) -> bool:
        """返回False表示此LLM不支持stop words"""
        return False


# 角色特定的默认配置 - 简化配置避免API兼容性问题
ROLE_CONFIGS = {
    "default": {
        "temperature": 0.7,
        "max_tokens": 4096,
        "timeout": 6000
        # 移除可能导致API兼容性问题的参数
    },
    "manager": {
        "temperature": 0.5,  # 更低的温度，确保决策一致性
        "max_tokens": 4096,
        "timeout": 6000
        # 移除可能导致API兼容性问题的参数
    },
    "researcher": {
        "temperature": 0.7,  # 适中的温度，保持创造性
        "max_tokens": 4096,
        "timeout": 6000
        # 移除可能导致API兼容性问题的参数
    },
    "analyst": {
        "temperature": 0.3,  # 更低的温度，确保分析准确性
        "max_tokens": 18000,  # 更大的token限制，支持详细报告
        "timeout": 6000
        # 移除可能导致API兼容性问题的参数
    }
}

def _get_required_env(env_name: str) -> str:
    """
    获取必需的环境变量，如果不存在则抛出错误
    
    Args:
        env_name: 环境变量名称
        
    Returns:
        环境变量的值
        
    Raises:
        ValueError: 如果环境变量不存在
    """
    value = os.getenv(env_name)
    if not value:
        raise ValueError(
            f"❌ 错误: 必需的环境变量 '{env_name}' 未设置。\n"
            f"   请在 .env 文件或系统环境变量中设置 {env_name}。"
        )
    return value

def _get_base_config() -> Dict[str, str]:
    """获取基础配置信息"""
    return {
        "api_base": os.getenv("OPENAI_API_BASE", DEFAULT_API_BASE),
        "api_key": os.getenv("OPENAI_API_KEY", DEFAULT_API_KEY)
    }

def _create_llm(model: str, role: str = "default", **overrides):
    """
    创建 LLM 配置的通用函数 - 使用最简配置避免API兼容性问题
    
    Args:
        model: 模型名称
        role: 角色类型 (default, manager, researcher, analyst)
        **overrides: 覆盖默认配置的参数
    """
    base_config = _get_base_config()
    role_config = ROLE_CONFIGS.get(role, ROLE_CONFIGS["default"])
    
    # 合并配置，overrides 优先级最高
    config = {**role_config, **overrides}
    
    # 创建LLM配置，只使用最基本的参数避免API兼容性问题
    llm_params = {
        "model": f"openai/{model}",
        "api_key": base_config["api_key"],
        "base_url": base_config["api_base"],
        "temperature": config.get("temperature", 0.7),
        "max_tokens": config.get("max_tokens", 4096),
        "timeout": config.get("timeout", 6000),
    }
    
    # 不再添加其他参数，避免API兼容性问题
    return CustomLLM(**llm_params)

def get_llm_config():
    """
    获取默认 LLM 配置：采用 OpenAI 调用方式 
    """
    model = _get_required_env("MODEL")
    return _create_llm(model, "default")

def get_manager_llm():
    """
    Manager使用的LLM配置
    使用更强大的模型进行任务协调和决策
    """
    model = _get_required_env("MANAGER_MODEL")
    return _create_llm(model, "manager")

def get_data_supporting_engineer_llm():
    """
    数据支持工程师使用的LLM配置
    使用默认配置进行数据处理
    """
    model = _get_required_env("DATA_ENGINEER_MODEL")
    return _create_llm(model, "default")

def get_risk_control_officer_llm():
    """
    风险控制官使用的LLM配置
    使用更保守的配置进行风险分析
    """
    model = _get_required_env("RISK_CONTROL_MODEL")
    return _create_llm(model, "manager")  # 使用manager配置，更保守

def get_quant_analyst_llm():
    """
    量化分析师使用的LLM配置
    使用分析师专用配置
    """
    model = _get_required_env("QUANT_ANALYST_MODEL")
    return _create_llm(model, "analyst")

def get_prediction_llm():
    """
    预测分析师使用的LLM配置
    使用分析师专用配置
    """
    model = _get_required_env("PREDICTION_MODEL")
    return _create_llm(model, "analyst")

def get_planning_llm():
    """
    规划者使用的LLM配置
    使用更强大的模型进行规划
    """
    model = _get_required_env("PLANNING_MODEL")
    return _create_llm(model, "manager")

# 导出各个配置
llm_config = get_llm_config()  # 默认配置
manager_llm = get_manager_llm()
planning_llm = get_planning_llm()
data_supporting_engineer_llm = get_data_supporting_engineer_llm()
risk_control_officer_llm = get_risk_control_officer_llm()
quant_analyst_llm = get_quant_analyst_llm()
prediction_llm = get_prediction_llm()

def print_llm_config():
    """打印当前 LLM 配置信息"""
    base_config = _get_base_config()
    try:
        model = _get_required_env("MODEL")
        print("🤖 LLM 配置信息:")
        print(f"  📝 模型: {model}")
        print(f"  🌐 API 地址: {base_config['api_base']}")
        print(f"  🔑 API 密钥: {base_config['api_key'][:10]}..." if base_config['api_key'] else "  🔑 API 密钥: 未设置")
        print(f"  🎯 调用方式: OpenAI 兼容格式")
        print(f"  🚀 实际模型: {model}")
    except ValueError as e:
        print(str(e))

if __name__ == "__main__":
    print_llm_config()
